import type { IUserInfo } from '@/api/user'
import { defineStore } from 'pinia'
import type { RouteRecordRaw } from 'vue-router'
import { asyncRoutes } from '@/router'

/**
 *
 * @param routes 路由数据
 * @param permissions 权限数据
 * @returns
 */
function filterRoutes(routes: RouteRecordRaw[], permissions: string[]) {
  return routes
    .map((item) => ({ ...item }))
    .filter((item) => {
      // 递归 item.children
      if (item.children && item.children.length) {
        item.children = filterRoutes(item.children, permissions)
      }
      return permissions.includes(item.name as string)
    })
}

function strToArr(str: string) {
  // 1. 按照 _ 分割字符串
  const arr = str.split('_')

  // 2. 使用 reduce 方法处理
  //    prev 上一次的返回结果
  //    item 当前项
  //    index 下标
  return arr.reduce((result, item, index) => {
    if (index === 0) {
      result.push(item)
    } else {
      result.push(`${result[index - 1]}_${item}`)
    }

    return result
  }, [] as string[])
}

export const usePermissionStore = defineStore('permission', {
  state() {
    return {
      isAddedRoute: false, // 是否已经动态添加过路由了
      routes: [] as RouteRecordRaw[] // 有权限的路由数据
    }
  },

  actions: {
    /**
     * 构建路由数据
     */
    async generateRoutes(userInfo: IUserInfo) {
      // 1. 得到 userInfo 中的 permissions、isAdmin
      const { permissions, isAdmin } = userInfo

      // BUG: 当  permissions 只有某个子级权限时，比如 ['dashboard_console'] 这时会有问题，我们需要带上父级的权限
      //      ['dashboard_console'] => ['dashboard', 'dashboard_console']
      //      ['system_user'] => ['system', 'system_user']

      const permissionsAll: string[] = []
      permissions.forEach((str) => {
        permissionsAll.push(...strToArr(str))
      })

      console.log('permissions', permissions)
      console.log('permissionsAll', permissionsAll)

      // 2. 过滤生成有权限的路由数据，要判断管理员
      const permissionRoutes = isAdmin ? asyncRoutes : filterRoutes(asyncRoutes, permissionsAll)

      // 3. 设置给 routes
      this.routes = permissionRoutes

      // 4. 返回这份数据
      return permissionRoutes
    }
  }
})
